#!/usr/bin/env python
# stoker_base: Base classes for Stoker internal structures
#
# Author:   Mike Murphy (mamurph@cs.clemson.edu)
# Revision: 26 February 2009
#
#   Copyright 2007-2009 Clemson University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# This material is based upon work supported under a National Science
# Foundation Graduate Research Fellowship. Any opinions, findings,
# conclusions or recommendations expressed in this publication are those of
# the author(s) and do not necessarily reflect the views of the National
# Science Foundation.

import sys, os.path
import external_command

from stoker_messages import MSG_WARNING, MSG_ERROR, MSG_SUMMARY_OK, \
         MSG_SUMMARY_FAIL, MSG_EXIT_CODE
from stoker_defines import SHORT_OPTIONS, LONG_OPTIONS, \
         ARGUMENTS, MIN_ARGS, MAX_ARGS, EXIT_SUCCESS


signal_monitor = external_command.SignalMonitor()


class MachineSourceBase(object):
   def __init__(self, stoker_config):
      self.config = stoker_config
      self.CLI_NAME = ''
   def resolveTargets(self, targets):
      # (resolved, unresolved) where resolved is a *list of dictionaries*
      return ([], targets[:])
   def getAllMachines(self):
      return []
   def getAllGroups(self):
      return []
#

class CommandObjectBase(object):
   def __init__(self, stoker_config, opts, args, target, extra):
      self.stoker_config = stoker_config
      self.opts = opts[:]
      self.args = args[:]
      self.target = target
      self.extra = extra
   #
   def execute(self, stdin=''):
      return (0, '', '') # code, stdout, stderr
   #
#

def pr_warning(msg):
   if type(msg) is list:
      for m in msg:
         print >> sys.stderr, MSG_WARNING, m
   else:
      print >> sys.stderr, MSG_WARNING, msg
#

def pr_error(msg, terminate=1):
   if type(msg) is list:
      for m in msg:
         print >> sys.stderr, MSG_ERROR, m
   else:
      print >> sys.stderr, MSG_ERROR, msg
   if terminate != 0:
      sys.exit(terminate)
#

def pr_summary(who, code):
   summary = MSG_SUMMARY_OK
   if code != EXIT_SUCCESS:
      summary = MSG_SUMMARY_FAIL
   print >> sys.stderr, who.strip() + ':', summary
#

def make_report(who, code, out, err):
   result = ''
   result += '-' * 79 + '\n'
   # mlen: length of target name, plus length of str repr of code number,
   # plus length of header (MSG_EXIT_CODE), plus 4 (2 spaces, 2 parens)
   mlen = len(who) + len(str(code)) + len(MSG_EXIT_CODE) + 5
   if mlen < 79:
      spaces = (79 - mlen) / 2
      result += ' ' * spaces + who + ' (' + MSG_EXIT_CODE + ' ' + \
               str(code) + ')\n'
   else:
      result += who + '\n'
   result += '-' * 79 + '\n'
   if len(out) > 0:
      result += out + '\n'
   result += '-' * 79 + '\n'
   if len(err) > 0:
      result += err + '\n'
   return result
#

def write_file(who, path, data):
   try:
      if os.path.isdir(path):
         filename = os.path.join(path, who)
         fh = open(filename, 'w')
         fh.write(data)
         fh.write('\n')
      else:
         fh = open(path, 'a')
         fh.write(data)
         fh.write('\n')
   except Exception, msg:
      print >> sys.stderr, msg
   if fh:
      try:
         fh.close()
      except Exception:
         pass
#

def run_external(command, args, stdin=''):
   return external_command.run_external(command, args, stdin, signal_monitor)
#
